package fr.sedoo.metadata.client.ui.widget.table.contact;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.cellview.client.TextColumn;

import fr.sedoo.commons.client.util.ListUtil;
import fr.sedoo.commons.client.util.UuidUtil;
import fr.sedoo.commons.client.widget.ConfirmCallBack;
import fr.sedoo.commons.client.widget.dialog.OkCancelDialog;
import fr.sedoo.commons.client.widget.table.AbstractListTable;
import fr.sedoo.commons.client.widget.table.multiline.MultiLineTextColumn;
import fr.sedoo.commons.shared.domain.HasIdentifier;
import fr.sedoo.metadata.client.message.MetadataMessage;
import fr.sedoo.metadata.client.ui.view.presenter.EditingPresenter;
import fr.sedoo.metadata.client.ui.widget.dialog.contact.ContactListDialogBoxContent;
import fr.sedoo.metadata.client.ui.widget.dialog.contact.PersonDTOEditor;
import fr.sedoo.metadata.shared.domain.dto.MetadataContactDTO;
import fr.sedoo.metadata.shared.domain.misc.IdentifiedString;

public class MetadataContactTable extends AbstractListTable {

	private ContactListDialogBoxContent listContent = null;

	private boolean editColumnInitialized = false;
	private boolean displayColumnInitialized = false;

	private EditingPresenter presenter;

	private List<String> roles;

	protected MetadataContactTable() {
		super();
	}

	public MetadataContactTable(String role) {
		this();
		List<String> aux = new ArrayList<String>();
		aux.add(role);
		roles = aux;
	}

	public MetadataContactTable(List<String> roles) {
		this();
		this.roles = roles;
	}

	@Override
	public void addItem() {

		MetadataContactDialogBoxContent content = new MetadataContactDialogBoxContent(roles);
		ConfirmCallBack callBack = new CreateConfirmCallBack(content);
		content.setConfirmCallBack(callBack);
		MetadataContactDTO newContact = new MetadataContactDTO();
		content.edit(newContact);
		OkCancelDialog dialog = new OkCancelDialog(MetadataMessage.INSTANCE.metadataContactTableAddItemText(), content);
		dialog.show();
	}

	@Override
	public String getAddItemText() {
		return MetadataMessage.INSTANCE.metadataContactTableAddItemText();
	}

	@Override
	public void presenterDelete(HasIdentifier hasIdentifier) {
		removeRow(hasIdentifier.getIdentifier());
	}

	@Override
	public void presenterEdit(HasIdentifier hasIdentifier) {
		final String id = hasIdentifier.getIdentifier();

		MetadataContactDialogBoxContent content = new MetadataContactDialogBoxContent(roles);
		ConfirmCallBack callBack = new EditConfirmCallBack(id, content);
		content.setConfirmCallBack(callBack);
		MetadataContactDTO contact = (MetadataContactDTO) getItemById(id);
		content.edit(contact);
		OkCancelDialog dialog = new OkCancelDialog(MetadataMessage.INSTANCE.metadataContactTableAddItemText(), content);
		dialog.show();
	}

	@Override
	protected void initColumns() {

	}

	public ContactListDialogBoxContent getListContent() {
		return listContent;
	}

	public void reset() {
		List<IdentifiedString> aux = new ArrayList<IdentifiedString>();
		init(aux);
	}

	public EditingPresenter getPresenter() {
		return presenter;
	}

	public void setPresenter(EditingPresenter presenter) {
		this.presenter = presenter;
	}

	public void enableEditMode() {
		setAddButtonEnabled(true);
		getToolBarPanel().setVisible(true);
		initEditColumns();
	}

	public void enableDisplayMode() {
		setAddButtonEnabled(false);
		getToolBarPanel().setVisible(false);
		initDisplayColumns();
	}

	protected void initEditColumns() {
		if (editColumnInitialized == false) {
			initLocalColumns();
			super.initColumns();
			setAddButtonEnabled(true);
			editColumnInitialized = true;
		}
	}

	private void initLocalColumns() {
		TextColumn<HasIdentifier> nameColumn = new TextColumn<HasIdentifier>() {
			@Override
			public String getValue(HasIdentifier aux) {
				return ((MetadataContactDTO) aux).getPersonName();
			}
		};
		itemTable.addColumn(nameColumn, MetadataMessage.INSTANCE.personPersonName());
		itemTable.setColumnWidth(nameColumn, 100.0, Unit.PX);

		TextColumn<HasIdentifier> emailColumn = new TextColumn<HasIdentifier>() {
			@Override
			public String getValue(HasIdentifier aux) {
				return ((MetadataContactDTO) aux).getEmail();
			}
		};
		itemTable.addColumn(emailColumn, MetadataMessage.INSTANCE.personEmail());
		itemTable.setColumnWidth(emailColumn, 100.0, Unit.PX);

		TextColumn<HasIdentifier> organisationColumn = new TextColumn<HasIdentifier>() {
			@Override
			public String getValue(HasIdentifier aux) {
				return ((MetadataContactDTO) aux).getOrganisationName();
			}
		};
		itemTable.addColumn(organisationColumn, MetadataMessage.INSTANCE.personOrganisationName());
		itemTable.setColumnWidth(organisationColumn, 100.0, Unit.PX);

		MultiLineTextColumn<HasIdentifier> adressColumn = new MultiLineTextColumn<HasIdentifier>() {
			@Override
			public String getValue(HasIdentifier aux) {
				return ((MetadataContactDTO) aux).getCompleteAdress();
			}
		};
		itemTable.addColumn(adressColumn, MetadataMessage.INSTANCE.personAddress());
		itemTable.setColumnWidth(adressColumn, 100.0, Unit.PX);

		if (roles.size() > ListUtil.SINGLETON_SIZE) {
			MultiLineTextColumn<HasIdentifier> roleColumn = new MultiLineTextColumn<HasIdentifier>(RoleRenderer.getInstance()) {
				@Override
				public String getValue(HasIdentifier aux) {
					return ((MetadataContactDTO) aux).getRoles();
				}
			};
			itemTable.addColumn(roleColumn, MetadataMessage.INSTANCE.personRoles());
			itemTable.setColumnWidth(roleColumn, 100.0, Unit.PX);
		}
	}

	protected void initDisplayColumns() {
		if (displayColumnInitialized == false) {
			initLocalColumns();
			displayColumnInitialized = true;
		}
	}

	private class EditConfirmCallBack implements ConfirmCallBack {
		PersonDTOEditor editor;
		String uuid;

		public EditConfirmCallBack(String uuid, PersonDTOEditor editor) {
			this.editor = editor;
			this.uuid = uuid;
		}

		@Override
		public void confirm(boolean choice) {
			if (choice == true) {
				MetadataContactDTO resultValue = (MetadataContactDTO) editor.getValue();
				resultValue.setUuid(uuid);
				// model.add(resultValue);
				List<MetadataContactDTO> newValues = new ArrayList<MetadataContactDTO>();
				Iterator<? extends HasIdentifier> iterator = model.listIterator();
				while (iterator.hasNext()) {
					MetadataContactDTO aux = (MetadataContactDTO) iterator.next();
					if (aux.getIdentifier().compareTo(uuid) == 0) {
						newValues.add(resultValue);
					} else {
						newValues.add(aux);
					}
				}
				init(newValues);
			}
		}
	}

	private class CreateConfirmCallBack implements ConfirmCallBack {
		PersonDTOEditor editor;

		public CreateConfirmCallBack(PersonDTOEditor editor) {
			this.editor = editor;
		}

		@Override
		public void confirm(boolean choice) {
			if (choice == true) {
				MetadataContactDTO resultValue = (MetadataContactDTO) editor.getValue();
				resultValue.setUuid(UuidUtil.uuid());
				List<MetadataContactDTO> newValues = new ArrayList<MetadataContactDTO>();
				Iterator<? extends HasIdentifier> iterator = model.iterator();
				while (iterator.hasNext()) {
					MetadataContactDTO aux = (MetadataContactDTO) iterator.next();
					newValues.add(aux);
				}
				newValues.add(resultValue);
				init(newValues);
			}
		}
	}

}
